﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace BleModeTool
{
    public partial class Form1 : Form
    {
        private const string openSpStr = "打开串口";
        private const string closeSpStr = "关闭串口";
        private List<byte> readList = new List<byte>(256);

        private string nameStr;
        private string pswdStr;
        public Form1()
        {
            InitializeComponent();

            UpDatePort();
            baudCmb.SelectedIndex = 0;
            typeCmb.SelectedIndex = 0;
            openBtn.Text = openSpStr;
            blueGrp.Enabled = false;
            hc05Grp.Enabled = false;
            pswdStr = "";
            nameStr = "";
        }

        #region 公共函数

        public void UpDatePort()
        {
            serialPortCmb.Items.Clear();

            foreach (string str in SerialPort.GetPortNames())
            {
                Regex reg = new Regex(@"COM\d{1,3}");
                serialPortCmb.Items.Add(reg.Match(str));
            }

            serialPortCmb.Items.Add("刷新");

            if (serialPortCmb.Items.Count > 1)
            { serialPortCmb.SelectedIndex = 0; }
        }

        #endregion

        #region 事件
        private void serialPortCmb_SelectedIndexChanged(object sender, EventArgs e)
        {
            
            if (serialPortCmb.SelectedIndex == serialPortCmb.Items.Count - 1)
            {
                UpDatePort();
                Console.WriteLine("刷新串口");
            }
        }

        private void openBtn_Click(object sender, EventArgs e)
        {
            if (openBtn.Text == openSpStr)
            {
                if ((serialPortCmb.Items.Count > 1) && (serialPortCmb.SelectedIndex != -1))
                {
                    spGrp.Enabled = false;
                    blueGrp.Enabled = true;
                    hc05Grp.Enabled = true;
                    openBtn.Text = closeSpStr;
                    //设置串口参数
                    mSerialPort.PortName = serialPortCmb.SelectedItem.ToString();
                    mSerialPort.BaudRate = int.Parse(baudCmb.SelectedItem.ToString());
                    mSerialPort.Open();

                    //sendTimer.Start();
                }
                else
                { MessageBox.Show("请选择正确的串口打开", "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error); }
            }
            else
            {
                openBtn.Text = openSpStr;
                mSerialPort.Close();
                spGrp.Enabled = true;
                blueGrp.Enabled = false;
                hc05Grp.Enabled = false;
            }
            
        }

        private void readBtn_Click(object sender, EventArgs e)
        {
            string header;

            switch (typeCmb.SelectedIndex)
            {
                case 0://HC05
                    header = "AT+NAME?\r\n";
                    break;
                case 1://HC02
                    header = "AT+RX\r\n";
                    break;
                case 2://CC2540
                    header = "AT+NAME?\r\n";
                    break;
                default:
                    header = "AT+NAME?\r\n";
                    break;
            }
            byte[] cmd = Encoding.Default.GetBytes(header);
            mSerialPort.Write(cmd, 0, header.Length);
        }

        private void writeBtn_Click(object sender, EventArgs e)
        {
            string header;

            switch (typeCmb.SelectedIndex)
            {
                case 0://HC05
                    header = "AT+NAME=" + nameTb.Text.ToString() + "\r\n";
                    break;
                case 1://HC02
                    header = "AT+NAME" + nameTb.Text.ToString();
                    break;
                case 2://CC2540
                    header = "AT+NAME" + nameTb.Text.ToString() + "\r\n";
                    break;
                default:
                    header = "AT+NAME=" + nameTb.Text.ToString() + "\r\n";
                    break;
            }
            byte[] cmd = Encoding.Default.GetBytes(header);
            mSerialPort.Write(cmd, 0, header.Length);

            MessageBox.Show("修改蓝牙名字成功");
        }

        private void readPasswordBtn_Click(object sender, EventArgs e)
        {
            string header;

            switch (typeCmb.SelectedIndex)
            {
                case 0://HC05
                    header = "AT+PSWD?\r\n";
                    break;
                case 1://HC02
                    header = "AT+RX\r\n";
                    break;
                case 2://CC2540
                    header = "AT+PSWD?\r\n";
                    break;
                default:
                    header = "AT+PSWD?\r\n";
                    break;
            }
            byte[] cmd = Encoding.Default.GetBytes(header);
            mSerialPort.Write(cmd, 0, header.Length);
        }

        private void writePasswordBtn_Click(object sender, EventArgs e)
        {
            string header;
            switch (typeCmb.SelectedIndex)
            {
                case 0://HC05
                    header = "AT+NAME=" + passwordTb.Text.ToString() + "\r\n";
                    break;
                case 1://HC02
                    header = "AT+PIN" + passwordTb.Text.ToString();
                    break;
                case 2://CC2540
                    header = "AT+NAME"+ passwordTb.Text.ToString() + "\r\n";
                    break;
                default:
                    header = "AT+NAME=" + passwordTb.Text.ToString() + "\r\n";
                    break;
            }
            byte[] cmd = Encoding.Default.GetBytes(header);
            mSerialPort.Write(cmd, 0, header.Length);

            MessageBox.Show("修改蓝牙密码成功");

        }



        #endregion

        #region 串口接收

        private void ProcessingData(object sender, EventArgs e)
        {
            currentNameTb.Text = nameStr;
            currentPasswordTb.Text = pswdStr;
        }
        private void mSerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            //1.缓存数据
            int num = mSerialPort.BytesToRead;
            byte[] data = new byte[num];
            mSerialPort.Read(data, 0, num);
            readList.AddRange(data);

            //2.完整性判断
            while (readList.Count >= 6)//至少要包含头（1字节）+地址（2字节）+长度（2字节）+1个校验
            {
                if (readList[0] == 'N' && readList[1] == 'A' && readList[2] == 'M' && readList[3] == 'E')
                {
                    int i = 5;
                    List<byte> rList = new List<byte>();

                    while (i < readList.Count)
                    {
                        //继续处理
                        if (readList[i] == '\r')
                        {
                            byte[] name = readList.ToArray();
                            nameStr = Encoding.Default.GetString(name);
                            readList.RemoveRange(0, 5);
                            this.Invoke(new EventHandler(ProcessingData));
                        }
                        else
                        {
                            rList.Add(readList[i]);
                        }
                        i++;

                    }
                    return;
                }
                else if (readList[0] == 'P' && readList[1] == 'S' && readList[2] == 'W' && readList[3] == 'D')
                {
                    int i = 5;
                    List<byte> rList = new List<byte>();

                    while (i < readList.Count)
                    {
                        //继续处理
                        if (readList[i] == '\r')
                        {
                            byte[] name = readList.ToArray();
                            pswdStr = Encoding.Default.GetString(name);
                            readList.RemoveRange(0, 5);
                            this.Invoke(new EventHandler(ProcessingData));
                        }
                        else
                        {
                            rList.Add(readList[i]);
                        }
                        i++;

                    }
                    return;
                }
                else if (readList[0] == 'P' && readList[1] == 'I' && readList[2] == 'N')
                {
                    int i = 4;
                    List<byte> rList = new List<byte>();

                    while (i < readList.Count)
                    {
                        //继续处理
                        if (readList[i] == '\r')
                        {
                            byte[] name = readList.ToArray();
                            pswdStr = Encoding.Default.GetString(name);
                            readList.RemoveRange(0, 4);
                            this.Invoke(new EventHandler(ProcessingData));
                        }
                        else
                        {
                            rList.Add(readList[i]);
                        }
                        i++;

                    }
                    return;
                }
                //这里是很重要的，如果数据开始不是头，则删除数据
                else { readList.RemoveAt(0); }
            }
        }

        #endregion

        private void typeCmb_SelectedIndexChanged(object sender, EventArgs e)
        {
            //HC05
            if (typeCmb.SelectedIndex == 0)
            { setHc05MasterBtn.Enabled = true; }
            else
            { setHc05MasterBtn.Enabled = false; }


            if (typeCmb.SelectedIndex == 2)
            { readNameBtn.Enabled = false; }
            else
            { readNameBtn.Enabled = true; }


        }


        
        private void setHc05MasterBtn_Click(object sender, EventArgs e)
        {
            //
            Task.Run(() => {

                //设置设备类型为0x040680 
                string header = "AT+CLASS=040680\r\n"; 
                byte[] cmd = Encoding.Default.GetBytes(header);
                mSerialPort.Write(cmd, 0, header.Length);

                Thread.Sleep(200);

                  //设置成主机
                header = "AT+ROLE=1\r\n";
                cmd = Encoding.Default.GetBytes(header);
                mSerialPort.Write(cmd, 0, header.Length);

                MessageBox.Show("修改HC05为主机成功!");

            });
            
        }


    }
}
